<?php
namespace jinpeng;

use think\facade\Env;

class Jinpeng {

	protected $appId;

	protected $appSecure;

	protected $host;

	protected $_debug=true;

	public function __construct() {
		$this->appId = Env::get('jinpeng.app_id');
		$this->appSecure = Env::get('jinpeng.app_secure');
		$this->host = Env::get('jinpeng.host');
		$this->_debug = Env::get('jinpeng.debug');
	}

	public function setConfig($config) {
		$this->appId = isset($config['app_id']) ? $config['app_id'] : '';
		$this->appSecure = isset($config['app_secure']) ? $config['app_secure'] : '';
		$this->host = isset($config['host']) ? $config['host'] : '';
		if(isset($config['debug'])) {
			$this->_debug = $config['debug'];
		}
		return $this;
	}

	/**
	 * 同步订单
	 *
	 * @author King
	 * @date 2021年4月19日
	 *
	 * @param string $action		增改删动作add,edit,dele
	 * @param integer $orderId		生产单内码
	 * @param string $orderNo		生产单号
	 * @param integer $skuId		款内码
	 * @param string $sku			款号
	 * @param array $detail			[{"color_id":"c-1","color":"红色","size_id":"XL","size":"XL","qty":"10","action":"add"}]
	 *
	 * @return array	["succeed":true,"msg":"","msg_code":"","data":""]
	 * "0000": "未定义错误"
		"1001": "签名错误";
		"1002": "与服务器时间差距大"
		"1003": "生产单资料已经存在"
		"1004": "裁单资料已经存在"
		"1005": "裁单已经上线:生产单不可删除"
		"1006": "裁单已经上线:款编号或名称不可修改"
		"1007": "菲票已经打印:款编号或名称不可修改"
		"1008": "裁单已经上线:裁单不可删除"
		"1010": "扎菲已经被领取:扎菲上数量不可修改"
		"1011": "扎菲已经被领取:扎菲不可删除"
		"1012": "删除失效,内码不存在"
	 */
	public function syncOrder($action, $orderId, $orderInfo, $skuId, $sku, $detail=[]) {
		try {
			$url = $this->host;
			$postData = [
				'APPID' => $this->appId,
				'METHOD' => 'prd_order_request',
				'TIMESTAMP' => time(),
				'VERSION' => '1.0',
				'action' => $action,
                'factory_id'=>$orderInfo['factory_id'],
                'factory_name'=>$orderInfo['factory_name'],
				'prd_order_id' => $orderId,
				'prd_order_no' => $orderInfo['client_ordernum'],
				'prd_id' => $skuId,
				'prd_no' => mb_convert_encoding($sku, 'gb2312'),
				'prd_name' => mb_convert_encoding($sku, 'gb2312'),

			];
			$postData['detail'] = bin2hex(mb_convert_encoding(json_encode($detail, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), 'gb2312'));
			$postData['SIGN'] = $this->_getSign($postData);

			$postDataTmp = $postData;
			$postDataTmp['detail'] = json_encode($detail, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
			$logId = $this->_addLog(1, $orderId, $orderInfo['client_ordernum'], $action, '', $postDataTmp);
			$result = $this->_httpPost($url, $postData);
			$this->_updateLog($logId, $result);
			return $result;
		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

	/**
	 * 同步裁床单
	 *
	 * @author King
	 * @date 2021年4月19日
	 *
	 * @param string $action		增改删动作add,edit,dele
	 * @param integer $orderId		生产单内码
	 * @param integer $orderNo		生产单号
	 * @param string $cutNo			裁床单号
	 * @param string $cutDate		裁床日期（2021-05-06）
	 * @param array $detail			[{action:动作 add\edit\dele,bar_num:扎号,color_id:颜色内码,size_id:尺码内码,qty:数量}]
	 * @throws \Exception
	 *
	 * @return array	["succeed":true,"msg":"","msg_code":"","data":""]
	 * "0000": "未定义错误"
		"1001": "签名错误";
		"1002": "与服务器时间差距大"
		"1003": "生产单资料已经存在"
		"1004": "裁单资料已经存在"
		"1005": "裁单已经上线:生产单不可删除"
		"1006": "裁单已经上线:款编号或名称不可修改"
		"1007": "菲票已经打印:款编号或名称不可修改"
		"1008": "裁单已经上线:裁单不可删除"
		"1010": "扎菲已经被领取:扎菲上数量不可修改"
		"1011": "扎菲已经被领取:扎菲不可删除"
		"1012": "删除失效,内码不存在"
	 */
	public function syncCut($action, $orderId, $orderInfo, $cutNo, $cutDate='', $detail=[]) {
		try {
			$url = $this->host;
			$postData = [
				'APPID' => $this->appId,
				'METHOD' => 'cut_ex_request',
				'TIMESTAMP' => time(),
				'VERSION' => '1.0',
				'action' => $action,
                'factory_id'=>$orderInfo['factory_id'],
                'factory_name'=>$orderInfo['factory_name'],
				'prd_order_id' => $orderId,
				'cut_id' => $cutNo,
				'cut_no' => $cutNo,
				'cut_date' => $cutDate,
			];
			$postData['detail'] = bin2hex(mb_convert_encoding(json_encode($detail, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), "gb2312"));
			$postData['SIGN'] = $this->_getSign($postData);
            $orderNo=$orderInfo['client_ordernum'];
			$postDataTmp = $postData;
			$postDataTmp['detail'] = json_encode($detail, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);

			$logId = $this->_addLog(2, $orderId, $orderNo, $action, $cutNo, $postDataTmp);
			$result = $this->_httpPost($url, $postData);
			$this->_updateLog($logId, $result);
			return $result;
		} catch (\Exception $e) {
			throw new \Exception('请求异常，'.$e->getMessage());
		}
	}

    /**
     * 同步sku工价信息
     * @author sparkguo
     * @date 2021年12月30日
     * @param string $sku		sku款号
     * @param array $processList			[{id:工序id ,sku:sku款号,process_name:工序名称,process_stage:所属工段,process_price:工序价格}]
     * @throws \Exception
     *
     * @return array	["succeed":true,"msg":"","msg_code":"","data":""]
     * "0000": "未定义错误"
     */
    public function synSkuProcess($sku, $processList=[]) {
        try {
            $url = $this->host;
            $postData = [
                'APPID' => $this->appId,
                'METHOD' => 'sku_process_request',
                'TIMESTAMP' => time(),
                'VERSION' => '1.0',
                'sku' => $sku
            ];
            $postData['sku']=$sku;
            $postData['process_list'] = bin2hex(mb_convert_encoding(json_encode($processList, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), "gb2312"));
            $postData['SIGN'] = $this->_getSign($postData);

            $postDataTmp = $postData;
            $postDataTmp['process_list'] = json_encode($processList, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);

            $logId = $this->_addLog(2, 0, '', 'add', 0, $postDataTmp);
            $result = $this->_httpPost($url, $postData);
            $this->_updateLog($logId, $result);
            return $result;
        } catch (\Exception $e) {
            //throw new \Exception('请求异常，'.$e->getMessage());
            $result['succeed']=false;//请求异常
            return $result;
        }
    }

    /**
     * 推送某个订单的sku的工价信息
     * @return string
     * @throws \Exception
     */
    public function syncSkuPrice($source, $orderId, $orderNo,  $sku, $detail=[]) {
        try {
            $url = $this->host;
            $postData = [
                'APPID' => $this->appId,
                'METHOD' => 'sku_process_request',
                'TIMESTAMP' => time(),
                'VERSION' => '1.0',
//                'action' => $action,
                'prd_order_id' => $orderId,
//                'prd_order_no' => $orderNo,
                'prd_id' => $sku,
                'flag_only'=>$orderNo
            ];
            //bin2hex(mb_convert_encoding(json_encode($detail, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), 'gb2312'));
            $postData['process_list'] = bin2hex(mb_convert_encoding(json_encode($detail, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE), 'gb2312'));
            $postData['SIGN'] = $this->_getSign($postData);
            $postDataTmp = $postData;
            //$postDataTmp['process_list_notjson']=$detail;
            $logId = $this->_addLog(3, $orderId, $orderNo, $source, '', $postDataTmp);
            $result = $this->_httpPost($url, $postData);
            $this->_updateLog($logId, $result);
            //return [$postData,$result,$detail];
            return $result;
        } catch (\Exception $e) {
            throw new \Exception('请求异常，'.$e->getMessage());
        }
    }

    /**
	 * 记录日志
	 *
	 * @author King
	 * @date 2021年4月19日
	 *
	 * @param integer $type
	 * @param integer $orderId
	 * @param string $clientOrdernum
	 * @param string $action
	 * @param integer $chuanghao
	 * @param array $requestBody
	 * @return number|string
	 */
	private function _addLog($type, $orderId, $clientOrdernum, $action, $chuanghao=0, $requestBody=[]) {
		$data = [
			'type' => $type,
			'order_id' => $orderId,
			'client_ordernum' => $clientOrdernum,
			'action' => $action,
			'chuanghao' => $chuanghao,
			'request_body' => json_encode($requestBody, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE),
			'create_time' => time(),
			'update_time' => time(),
		];
		return db('jinpeng_api_log')->insertGetId($data);
	}

	/**
	 * 更新日志
	 *
	 * @author King
	 * @date 2021年4月19日
	 *
	 * @param integer $logId
	 * @param array $result
	 * @return number
	 */
	private function _updateLog($logId, $result) {
		$responseBody = '';
		if(isset($result['data']) && $result['data'] != '') {
			if (is_array($result['data'])) $responseBody = json_encode($result['data'], JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
			else $responseBody = $result['data'];
		}
		$data = [
			'response_status' => arrayGet($result, 'result', '') == true?1:0,
			'response_code' => arrayGet($result, 'msg_code', ''),
			'response_message' => arrayGet($result, 'msg', ''),
			'response_body' => $responseBody,
			'update_time' => time(),
		];
		return db('jinpeng_api_log')->where('id', $logId)->update($data);
	}

	/**
	 * 获取签名
	 *
	 * @author King
	 * @date 2021年4月19日
	 *
	 * @param array $data
	 * @return string
	 */
	private function _getSign($data) {
		ksort($data);
		$str = $this->appSecure;
		foreach ($data as $k => $v) {
			if($v == '') continue;
			$str .= $k.$v;
		}
		$str .= $this->appSecure;
		return strtoupper(md5($str));
	}

	/**
	 * 发送http请求
	 *
	 * @author KING
	 * @date 2019年4月10日
	 *
	 * @param string $url		请求URL
	 * @param array $data		请求参数
	 * @param integer $timeout	超时时间
	 * @param array $headers	请求头
	 * @return string
	 */
	private function _httpPost($url, $data, $timeout=30, $headers=array()){ // 模拟提交数据函数
		$curl = curl_init(); // 启动一个CURL会话
		curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($curl, CURLOPT_POST, true); // 发送一个常规的Post请求

		curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); // Post提交的数据包

		curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); // 设置超时限制防止死循环
		curl_setopt($curl, CURLOPT_HEADER, false); // 显示返回的Header区域内容
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
		curl_setopt($curl, CURLINFO_HEADER_OUT, $this->_debug?true:false); // 启用时,追踪句柄的请求字符串。
		$body = curl_exec($curl); // 执行操作
		$body = trim(stripslashes($body), '"');

		if ($this->_debug) {
			$requestHeader = curl_getinfo($curl, CURLINFO_HEADER_OUT);
			addLog(['url' => $url, 'header' => $requestHeader, 'body' => http_build_query($data), 'response' => $body], "jinpeng_api_debug");
		}

		if (curl_errno($curl)) {
			throw new \Exception(curl_error($curl));
		}
		curl_close($curl); // 关键CURL会话

		$result = json_decode($body, true);
		if(json_last_error() != JSON_ERROR_NONE) {
			throw new \Exception('响应数据解析失败');
		}
		return $result; // 返回数据
	}

}

?>